/*
 Copyright 2009 Abdulla Abdurakhmanov (abdulla@latestbit.com)
 Original sources are available at www.latestbit.com

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.

 StdHandshakeManager.hpp. Created on: 29.09.2009 15:26:46 
 */

#ifndef STDHANDSHAKEMANAGER_HPP_
#define STDHANDSHAKEMANAGER_HPP_

#include "smartobjects/SmartObjectsDefs.hpp"
#include "smartobjects/encrypters/IAsymmetricDataEncrypter.hpp"
#include "smartobjects/encrypters/ISymmetricDataEncrypter.hpp"
#include "smartobjects/coders/HandshakeRequest.hpp"
#include "smartobjects/coders/HandshakeResponse.hpp"
#include "IHandshakeManagerFactory.hpp"
#include "IHandshakeManager.hpp"
#include "IConnection.hpp"

namespace smartobjects {

class StdHandshakeManager : public IHandshakeManager {
public:
	SO_DLLPRFX StdHandshakeManager(IHandshakeManagerFactory* poFactory, IConnection* poConnection);
	SO_DLLPRFX virtual ~StdHandshakeManager();

	SO_DLLPRFX virtual bool isHandshaked() ;
	SO_DLLPRFX virtual void beginHandshake( );
	SO_DLLPRFX virtual void onHandshakeReceived ( ByteBuffer* poBuffer ) ;
	SO_DLLPRFX virtual void reset() ;
	SO_DLLPRFX virtual IConnection* getConnection() ;

protected:
	SO_DLLPRFX static const std::string SO_STD_HANDSHAKE_TYPE;

	enum HandshakeStatus {
		WAITING_TO_BEGIN_HANDSHAKE,
		WAITING_TO_PUBLIC_KEY,
		WAITING_TO_AUTH,
		WAITING_TO_SYMMETRIC_KEY,
		HANDSHAKED,
		HANDSHAKE_ERROR
	};

protected:
	SO_DLLPRFX virtual void sendHandshakeBegin(StdNetworkCommand* poCommand );

	SO_DLLPRFX virtual void onHandshakeRequestReceived(HandshakeRequest* poRequest);
	SO_DLLPRFX virtual void sendErrorHandshakeResponse(HandshakeRequest* poRequest, const SystemException& oEx);
	SO_DLLPRFX virtual void onReceiveClientBeginHandshake(HandshakeRequest* poRequest);
	SO_DLLPRFX virtual void onReceiveClientSymmetricKey(HandshakeRequest* poRequest);
	SO_DLLPRFX virtual void onReceiveClientAuth(HandshakeRequest* poRequest);

	SO_DLLPRFX virtual void onHandshakeResponseReceived(HandshakeResponse* poResponse);
	SO_DLLPRFX virtual void onReceiveServerPublicKey (HandshakeResponse*  poResponse );
	SO_DLLPRFX virtual void onReceiveServerSymmetricKey (HandshakeResponse*  poResponse );
	SO_DLLPRFX virtual void onReceiveServerFinishHandshake (HandshakeResponse*  poResponse );
	SO_DLLPRFX virtual void onReceiveHandshakeError(HandshakeResponse* poResponse);


protected:
	IHandshakeManagerFactory* m_poFactory;
	IConnection* m_poConnection;
	HandshakeStatus m_nHandshakeStatus;

	ByteBuffer* m_poHandshakeBuffer;
	ByteBuffer* m_poBufferToCrypt;

	PublicKey* m_poRemotePublicKey;
	IAsymmetricDataEncrypter* m_poRemoteAsymmetricEncrypter;
};

}

#endif /* STDHANDSHAKEMANAGER_HPP_ */
